package lt.inkredibl.iit.action;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.SpringLayout.Constraints;

public class SpringUtils
{

	public void setComps(Container container, Component[][] comps, Spring hspace, Spring vspace)
	{
		SpringLayout layout = (SpringLayout)container.getLayout();
		Spring singleWidth = null;
		List<Spring> widths = new ArrayList<Spring>();
		Spring height = vspace;
		for (Component[] row: comps)
		{
			for (Component comp: row)
			{
				container.add(comp);
			}
			if (row.length == 0)
			{
				height = sum(height, vspace);
			}
			else if (row.length == 1)
			{
				Constraints c = layout.getConstraints(row[0]);
				singleWidth = max(singleWidth, c.getWidth());
				c.setY(height);
				height = sum(height, c.getHeight());
			}
			else
			{
				Spring h = null;
				while (row.length > widths.size())
				{
					widths.add(null);
				}
				
				for (int i = 0; i < row.length; i++)
				{
					Component comp = row[i];
					Constraints c = layout.getConstraints(comp);
					widths.set(i, max(widths.get(i), c.getWidth()));
					c.setY(height);
					h = max(h, c.getHeight());
				}
				height = sum(height, h);
			}
			
			height = sum(height, vspace);
		}
		List<Spring> xes = new ArrayList<Spring>();
		xes.add(hspace);
		for (int i = 0; i < widths.size(); i++)
		{
			xes.add(sum(hspace, sum(xes.get(i), widths.get(i))));
		}
		for (Component[] row: comps)
		{
			if (row.length == 1)
			{
				Constraints c = layout.getConstraints(row[0]);
				c.setX(xes.get(0));
			}
			if (row.length > 1)
			{
				for (int i = 0; i < row.length; i++)
				{
					layout.getConstraints(row[i]).setX(xes.get(i));
				}
			}
		}
		Constraints cpc = layout.getConstraints(container);
		cpc.setWidth(max(sum(sum(hspace, singleWidth), hspace), xes.get(xes.size()-1)));
		cpc.setHeight(height);
	}

	Spring max(Spring s1, Spring s2)
	{
		return s1 != null ? (s2 != null ? Spring.max(s1, s2) : s1) : s2;
	}

	Spring sum(Spring s1, Spring s2)
	{
		return s1 != null ? (s2 != null ? Spring.sum(s1, s2) : s1) : s2;
	}

	public Component prefH(Component comp)
	{
		Dimension pref = comp.getPreferredSize();
		pref.height *= 2;
		comp.setMaximumSize(pref);
		return comp;
	}

	public Component maxW(Component comp)
	{
		Dimension max = comp.getMaximumSize();
		max.width = Integer.MAX_VALUE;
		comp.setMaximumSize(max);
		return comp;
	}

	String d(Dimension dim)
	{
		return dim.width+"x"+dim.height;
	}

	void d(Component c)
	{
		System.out.println(c.getClass().getSimpleName()+" ["+d(c.getMinimumSize())+" - "+d(c.getPreferredSize())+" - "+d(c.getMaximumSize())+"]");
	}

	public void d(Spring s)
	{
		Class cls = s.getClass();
		System.out.println(cls.getSimpleName()+" {");
		List<Field> fieldlist = new ArrayList<Field>();
		while (Spring.class.isAssignableFrom(cls))
		{
			fieldlist.addAll(Arrays.asList(cls.getDeclaredFields()));
			cls = cls.getSuperclass();
		}
	
		for (Field f: fieldlist)
		{
			try
			{
				System.out.print(f.getName()+" = ");
				f.setAccessible(true);
				Object value = f.get(s);
				if (value instanceof Spring) d((Spring)value);
				else if (value instanceof Component) d((Component)value);
				else System.out.println(value);
			}
			catch (IllegalArgumentException e)
			{
				e.printStackTrace();
			}
			catch (IllegalAccessException e)
			{
				e.printStackTrace();
			}
		}
		System.out.println("}");
	}

}
